#include <cstdio>
#include <vector>
#include <exception>
#include <iostream>
#include <string>

#include "debug.hpp"

namespace zen {

	namespace debug {

		std::vector<std::string> Callstack::cstack;
		std::string Callstack::lastLog;

		#ifdef ZEN_DEBUG_FILE
		FILE* Callstack::logFile = NULL;
		#endif

		Callstack::Callstack(std::string function) {
			cstack.push_back(function);
		}

		Callstack::~Callstack() {
			cstack.pop_back();
		}

		void Callstack::log(std::string message) {
			if (message != "") {
				if (lastLog != cstack.back()) {
					print_callstack();
					lastLog = cstack.back();
				}
				out("\t", Start);
				out(message, Continue);
				out("\n", Finish);
			}
		}

		void Callstack::out(std::string log, WritePhase phase) {
			#ifdef ZEN_DEBUG_CONSOLE
				if (log.length() > 0) {
					std::cout << log;
					if (phase == Finish)
						std::flush(std::cout);
				}
			#endif
			#ifdef ZEN_DEBUG_FILE
				if (log.length() > 0) {
					if (logFile == NULL)
						logFile = fopen(ZEN_DEBUG_FILE, "w");
					fwrite(log.c_str(), log.length(), 1, logFile);
					fflush(logFile);
				}
			#endif
			#ifdef ZEN_DEBUG_CUSTOM
				if (log.length() > 0) {
					std::ostream& ostream = ZEN_DEBUG_CUSTOM;
					ostream << log;
					if (phase == Finish)
						std::flush(ostream);
				}
			#endif
		}

		void Callstack::print_callstack() {
			out("", Start);
			for(unsigned int i = 0; i < cstack.size(); i++) {
				out(i == 0 ? "" : " > ", Continue);
				out(cstack[i], Continue);
			}
			out("\n", Finish);
		}


	} // namespace zen_debug

} // namespace zen_debug
		